package com.realife.eson.common.util.ognl;

import lombok.extern.slf4j.Slf4j;
import ognl.Ognl;
import ognl.OgnlContext;
import ognl.OgnlException;
import ognl.ParseException;

/**
 * @version V1.0
 * @author: guangcheng
 * @date: 2022/4/13 13:34
 * @description:
 */
@Slf4j
public class OGNLDemo {


    /**
     * 支持对象方法调用，如：×××.doSomeSpecial();
     * 支持类静态的方法调用和值访问，表达式的格式
     * @[类全名（包括包路径）]@[方法名 |  值名]，例如:
     * @java.lang.String@format('foo %s', 'bar')
     * 或@tutorial.MyConstant@APP_NAME
     *
     * 支持赋值操作和表达式串联，
     * price=100, discount=0.8, calculatePrice(), 这个表达式会返回80
     *
     * @param args
     * @throws ParseException
     * @throws OgnlException
     */
    public static void main(String[] args) throws ParseException, OgnlException {
//        ognlDemo2();
//        ognl2();
//        staticDemo();
        acDemo();
    }


    /**
     * 根搜索
     *
     * @return
     */
    public static String ognlDemo2() {

        try {

            OgnlContext context = new OgnlContext();

            Pet pet = new Pet();
            pet.setNick("ahua");
            User user1 = new User();
            user1.setId(100);
            user1.setName("Jack");
            user1.setPet(pet);
            //
            context.setRoot(user1);

            //根元素直接使用id,不需要加#号
            Object ognl1 = Ognl.parseExpression("id");//构建Ognl表达式
            Object value2 = Ognl.getValue(ognl1, context, context.getRoot());//解析表达式
            System.out.println(value2);

            Object exp1 = Ognl.parseExpression("pet.nick");
            Object v1 = Ognl.getValue(exp1, context, context.getRoot());
            System.out.println("v1 = " + v1);

        } catch (Exception e) {
            log.info("[**{}**]", e.getMessage());
        } finally {

        }

        return "";
    }


    /**
     * 标签演示
     */
    public static void ognl2() {

        try {
            //创建一个Ognl上下文对象
            OgnlContext context = new OgnlContext();
            /**
             * 1.OgnlContext放入基本变量数据
             */
            //放入数据
            context.put("cn", "China");
            //获取数据（map）
            String value = (String) context.get("cn");
            System.out.println(value);
            /**
             * 2.OgnlContext放入对象数据
             */
            //创建对象，设置对象属性
            User user = new User();
            user.setId(100);
            user.setName("Jack");
            user.setPet(new Pet("ahua"));
            //【往非根元素放入数据，取值的时候表达式要用"#"】
            context.put("user", user);
            //获取对象属性
            //使用这种方式也可以获取
            Object s = context.get("user");
            System.out.println(s);

            //使用Ognl表达式来获取
            //举例：例如标签<s:a value="#user.pet">取值，实际上就是运行了下面的代码获取的
            //先构建一个Ognl表达式，再解析表达式
            Object ognl = Ognl.parseExpression("#user.pet");//构建Ognl表达式
            Object value1 = Ognl.getValue(ognl, context, context.getRoot());//解析表达式
            System.out.println(value1);

        } catch (Exception e) {
            log.info("[**{}**]", e.getMessage());
        } finally {

        }

    }


    /**
     * 调用静态方法
     */
    public static void staticDemo() {
        try {

            //创建一个Ognl上下文对象
            OgnlContext context = new OgnlContext();

            //Ognl表达式语言，调用类的静态方法
            Object ognl = Ognl.parseExpression("@Math@floor(10.9)");
            //由于Math类在开发中比较常用，所有也可以这样写
//            Object ognl = Ognl.parseExpression("@@floor(10.9)");
            Object value = Ognl.getValue(ognl, context, context.getRoot());
            System.out.println(value);

        } catch (Exception e) {
            log.info("[**{}**]", e.getMessage());
        } finally {

        }
    }


    public static void acDemo() {

        try {

            OgnlContext context = new OgnlContext();
            context.put("country", "China");
            context.put("language", "Chinese");

            Object obj1 = Ognl.parseExpression("#country"); //解析ognl表达式
            Object v1 = Ognl.getValue(obj1, context, context.getRoot());//获取ognl的表达式值,obj1是上面一个api，其他两个分别是创建的上下文对象以及一个不用修改的参数
            System.out.println("v1 = " + v1);
            Object obj2 = Ognl.parseExpression("#language.toUpperCase()"); //方法调用
            Object v2 = Ognl.getValue(obj2, context, context.getRoot());
            System.out.println("v2 = " + v2);
            Object obj3 = Ognl.parseExpression("@java.lang.Integer@toBinaryString(10)");//等同于上面
            Object v3 = Ognl.getValue(obj3, context, context.getRoot());
            System.out.println("v3 = " + v3);
            Object obj4 = Ognl.parseExpression("@@min(10,4)"); //Math类的方法直接调用,静态方法的调用
            Object v4 = Ognl.getValue(obj4, context, context.getRoot());
            System.out.println("v4 = " + v4);

            Object exp5 = Ognl.parseExpression("@java.lang.String@format('foo %s', 'bar')");
            Object v5 = Ognl.getValue(exp5, context, context.getRoot());
            System.out.println("v5 = " + v5);

            String msg = "peter";
            String format = String.format(msg + " %s", "hello");
            System.out.println("format = " + format);

        } catch (Exception e) {
            log.info("[**{}**]", e.getMessage());
        } finally {

        }

    }
}

